/*
 * XAbstractSnapshot.java, created on Oct 20, 2005
 * 
 * Copyright (c) 2005 - 2007
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.xfc.model;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import org.xfc.util.XUtils;

/**
 *
 *
 * @author Devon Carew
 */
public abstract class XAbstractSnapshot
	implements XSnapshot
{
	private Long 	id;
	private long 	objectStamp;
	
	private boolean active;
	private boolean modified;
	private boolean deleted;
	
	// TODO: permissions flags?
	
	
	// TODO: the concept of updating, batching up property changes -
	
	
	private PropertyChangeSupport eventSupport = new PropertyChangeSupport(this);
	
	
	/**
	 * 
	 */
	public XAbstractSnapshot()
	{
		
	}
	
	/**
	 * @param id
	 * @param objectStamp
	 */
	public XAbstractSnapshot(Long id, long objectStamp)
	{
		this.id = id;
		this.objectStamp = objectStamp;
	}
	
	
	/**
	 * @return Returns the active.
	 */
	public boolean isActive()
	{
		return active;
	}
	
	/**
	 * @param active The active to set.
	 */
	public void setActive(boolean active)
	{
		this.active = active;
	}
	
	/**
	 * @return Returns the deleted.
	 */
	public boolean isDeleted()
	{
		return deleted;
	}
	
	/**
	 * @param deleted The deleted to set.
	 */
	public void setDeleted(boolean deleted)
	{
		this.deleted = deleted;
		
		if (deleted)
			setModified(true);
	}
	
	/**
	 * @return Returns the modified.
	 */
	public boolean isModified()
	{
		return modified;
	}
	
	/**
	 * @param modified The modified to set.
	 */
	public void setModified(boolean modified)
	{
		this.modified = modified;
	}
	
	/**
	 * @return Returns the id.
	 */
	public Long getId()
	{
		return id;
	}
	
	/**
	 * @param id The id to set.
	 */
	public void setId(Long id)
	{
		this.id = id;
	}
	
	/**
	 * @return Returns the objectStamp.
	 */
	public long getObjectStamp()
	{
		return objectStamp;
	}
	
	/**
	 * @param objectStamp The objectStamp to set.
	 */
	public void setObjectStamp(long objectStamp)
	{
		this.objectStamp = objectStamp;
	}
	
	// Property change support
	
	/** {@inheritDoc} */
	public void addPropertyChangeListener(PropertyChangeListener listener)
	{
		eventSupport.addPropertyChangeListener(listener);
	}
	
	/** {@inheritDoc} */
	public void addPropertyChangeListener(String property, PropertyChangeListener listener)
	{
		eventSupport.addPropertyChangeListener(property, listener);
	}
	
	/** {@inheritDoc} */
	public void removePropertyChangeListener(PropertyChangeListener listener)
	{
		eventSupport.removePropertyChangeListener(listener);
	}
	
	/** {@inheritDoc} */
	public void removePropertyChangeListener(String property, PropertyChangeListener listener)
	{
		eventSupport.removePropertyChangeListener(property, listener);
	}
	
	/**
	 * @param property
	 * @param oldValue
	 * @param newValue
	 * @param markAsModified
	 */
	protected void firePropertyChange(String property, boolean oldValue, boolean newValue, boolean markAsModified)
	{
		firePropertyChange(property, Boolean.valueOf(oldValue), Boolean.valueOf(newValue), markAsModified);
	}
	
	/**
	 * @param property
	 * @param oldValue
	 * @param newValue
	 * @param markAsModified
	 */
	protected void firePropertyChange(String property, int oldValue, int newValue, boolean markAsModified)
	{
		firePropertyChange(property, new Integer(oldValue), new Integer(newValue), markAsModified);
	}
	
	/**
	 * @param property
	 * @param oldValue
	 * @param newValue
	 * @param markAsModified
	 */
	protected void firePropertyChange(String property, Object oldValue, Object newValue, boolean markAsModified)
	{
		if (markAsModified && !isModified())
			setModified(true);
		
		eventSupport.firePropertyChange(property, oldValue, newValue);
	}
		
	/**
	 * @return the PropertyChangeSupport instance used to fire PropertyChangedEvents and
	 *         manager PropertyChangelisteners
	 */
	protected PropertyChangeSupport getPropertyChangeSupport()
	{
		return eventSupport;
	}
	
	// TODO: hibernate recommens equals and hashcode be based on the business key
	
	/** {@inheritDoc} */
	public boolean equals(Object object)
	{
		if (!(object instanceof XSnapshot))
			return false;
		
		return getId() == ((XSnapshot)object).getId();
	}
	
	/** {@inheritDoc} */
	public int hashCode()
	{
		Long id = getId();
		
		return id == null ? 0 : (int)((id.longValue() >> 32) ^ id.longValue());
	}
	
	/** {@inheritDoc} */
	public String toString()
	{
		String idString = (getId() == null ? "<no id>" : getId().toString());
		
		return "[" + XUtils.getShortName(getClass()) + " " + idString + "]";
	}
	
}
